package com.shark.security.jwt.configuration;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import com.shark.security.jwt.security.JwtAuthenticationEntryPoint;
import com.shark.security.jwt.security.MyAuthenticationProvider;
import com.shark.security.jwt.security.filter.JwtAuthenticationTokenFilter;
import com.shark.security.jwt.security.handler.MyAccessDeniedHandler;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private JwtAuthenticationEntryPoint unauthorizedHandler;

//    @Autowired
//    private UserDetailsService userDetailsService;
    
    @Autowired
    private MyAuthenticationProvider authenticationProvider;
    
    @Autowired
    private MyAccessDeniedHandler accessDeniedHandler;

    @Bean
    public JwtAuthenticationTokenFilter authenticationTokenFilterBean() throws Exception {
        return new JwtAuthenticationTokenFilter();
    }

//    @Bean
//    public PasswordEncoder passwordEncoder() {
//        return NoOpPasswordEncoder.getInstance();
//    }

//    @Autowired
//    public void configureAuthentication(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
//    	authenticationManagerBuilder.authenticationProvider(authenticationProvider);
////        authenticationManagerBuilder
////                // 设置UserDetailsService
////                .userDetailsService(this.userDetailsService)
////                // 使用BCrypt进行密码的hash
////                .passwordEncoder(passwordEncoder());
//    }
    
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    	auth.authenticationProvider(authenticationProvider);
	}

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity
                // 使用JWT，不需要csrf
                .csrf().disable()
                // 认证失败处理、无权访问失败处理
                .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).accessDeniedHandler(accessDeniedHandler).and()
                // 基于Token，不使用Session
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
                // 请求授权
                .authorizeRequests()
                // 允许对于网站静态资源的无授权访问
                .antMatchers(
                        HttpMethod.GET,
                        "/",
                        "/*.html",
                        "/favicon.ico",
                        "/**/*.html",
                        "/**/*.css",
                        "/**/*.js"
                ).permitAll()
                // 授权api放开
                .antMatchers("/api/auth/**").permitAll()
                // 禁用其他链接（需要认证）
                .anyRequest().authenticated();
        		// 授权判断
                // .anyRequest().access("@rbacService.hasPermission(request,authentication)");

        // 添加JWT filter
        httpSecurity
                .addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);
        // 禁用缓存
        httpSecurity.headers().cacheControl();
    }
}